package managedbean;

import entity.FnBBranchEntity;
import entity.FoodTypeEntity;
import entity.MealEntity;
import entity.ProductEntity;
import entity.SetMealEntity;
import entity.StakeholderEntity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import javax.faces.model.SelectItem;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.SelectEvent;
import session.stateful.MealSessionBean;
import session.stateful.ProductSessionBean;
import util.exception.DeleteProductException;

/**
 *
 * @author TrungHieu-Henry
 */
@ManagedBean(name = "mealManagerBean")
@SessionScoped
public class MealManagerBean {

    @EJB
    private MealSessionBean mealSessionBean;
    @EJB
    private ProductSessionBean productSessionBean;
    private String name;
    private List<MealEntity> mealList;
    private List<SetMealEntity> setMealList;
    private MealEntity selectedMeal;
    private MealEntity[] selectedMeals;
    private MealEntity[] selectedMeals_update;
    private SetMealEntity selectedSetMeal;
    private Long option;
    private List options = new ArrayList();
    private List<FoodTypeEntity> foodTypes = new ArrayList<FoodTypeEntity>();
    private boolean reload = true;
    private boolean reloadAddSet = true;
    private boolean reloadAddMeal = true;
    private boolean reloadUpdateSetMeal = true;
    private String statusMessage;
    private FnBBranchEntity selectedBranch;
    private List<MealEntity> mealOfBranch;

    public MealManagerBean() {
        selectedMeal = new MealEntity();
        selectedSetMeal = new SetMealEntity();
    }

    public void initAddMeal(PhaseEvent event) throws IOException {
        if (!checkBranch()) {
            return;
        }
        if (reloadAddMeal) {
            selectedMeal = new MealEntity();
            reloadAddMeal = false;
        }
        if (foodTypes.isEmpty()) {
            foodTypes = productSessionBean.getFoodType();
            for (int i = 0; i < getFoodTypes().size(); i++) {
                options.add(new SelectItem(getFoodTypes().get(i).getId(), getFoodTypes().get(i).getName()));
            }
            setReload(false);
        }
    }
    //save Meal and SetMeal

    public void initUpdateSetMeal(PhaseEvent event) throws IOException {
        if (reloadUpdateSetMeal) {
            if (!checkSetMeal())
                return;
            mealOfBranch = mealSessionBean.getMealListOfABranch(selectedBranch.getId());
            System.out.println("AAAAA");
            selectedMeals_update = mealSessionBean.getMealBySetMealId(selectedSetMeal.getId());
            System.out.println("BBBB");
            reloadUpdateSetMeal = false;
        }
    }

    public void initUpdateMeal(PhaseEvent event) throws IOException {
        reload = true;
        if (!checkMeal())
            return;
    }

    public void saveMeal(ActionEvent event) {
        mealSessionBean.addMeal(selectedMeal, option, selectedBranch.getId());
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Add New Meal Result: successful! (New meal is " + selectedMeal.getName() + ")", ""));
        selectedMeal = new MealEntity();
    }

    public void saveSetMeal(ActionEvent event) {
        mealSessionBean.addSetMeal(selectedSetMeal, selectedMeals, selectedBranch.getId());
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Add New Meal Result: successful! (New Set meal is " + selectedSetMeal.getName() + ")", ""));
        reloadAddSet = true;
    }

    //upload
    public void handleImageUpload(FileUploadEvent event) throws AbortProcessingException, NoSuchAlgorithmException {
        try {
            System.out.println("Try to upload image");
            System.out.println(event.getFile().getFileName());
            String filePath = "C:\\Users\\Dell\\Desktop\\Temp\\IS3102Project\\IS3102Project-war\\web\\images";
            File result = new File(filePath + System.getProperty("file.separator") + event.getFile().getFileName().replace(" ", "_"));
            FileOutputStream out = new FileOutputStream(result);
            int a;
            int BUFFER_SIZE = 8192;
            byte[] buffer = new byte[BUFFER_SIZE];
            InputStream is = event.getFile().getInputstream();
            while (true) {
                a = is.read(buffer);
                if (a < 0) {
                    break;
                }
                out.write(buffer, 0, a);
                out.flush();
            }

            selectedMeal.setImageLink(event.getFile().getFileName().replace(" ", "_"));
            out.close();
            is.close();

            FacesMessage msg = new FacesMessage("Succesful " + event.getFile().getFileName() + " is uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void handleImageUploadMeal(FileUploadEvent event) throws AbortProcessingException, NoSuchAlgorithmException {
        System.out.println(event.getFile().getFileName());
        selectedMeal.setImageLink(event.getFile().getFileName().replace(" ", "_"));
        System.out.println(selectedMeal.getImageLink());
        handleImageUpload(event);
    }

    public void handleImageUploadSetMeal(FileUploadEvent event) throws AbortProcessingException, NoSuchAlgorithmException {
        selectedSetMeal.setImageLink(event.getFile().getFileName().replace(" ", "_"));
        handleImageUpload(event);
    }

    //
    public void initMealList(PhaseEvent event) throws IOException {
        if (!checkBranch())
            return;
        
        mealList = mealSessionBean.getMealListOfABranch(selectedBranch.getId());

        if (reloadAddSet) {
            selectedSetMeal = new SetMealEntity();
            reloadAddSet = false;
        }
    }

    public void initSetMealList(PhaseEvent event) throws IOException {
        if(!checkBranch())
            return;
        setMealList = mealSessionBean.getSetMealListOfABranch(selectedBranch.getId());
    }

    public List<MealEntity> getMealList() {
        return mealList;
    }

    public String onRowSelectNavigateMeal(SelectEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedMeal", event.getObject());
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedProduct", event.getObject());
        reloadAddMeal = true;
        return "StakeholderUpdateSelectedMeal?faces-redirect=true";
    }

    public String onRowSelectNavigateSetMeal(SelectEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedSetMeal", event.getObject());
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedProduct", event.getObject());
        reloadAddSet = true;
        return "StakeholderUpdateSelectedSetMeal?faces-redirect=true";
    }

    //update Meal and Set Meal
    public void updateMeal(ActionEvent event) {
        mealSessionBean.updateMeal(selectedMeal);
    }

    public void updateSetMeal(ActionEvent event) {
        mealSessionBean.updateSetMeal(selectedSetMeal, getSelectedMeals_update());
    }

    public void deleteMeal(ActionEvent event) {
        System.out.println("1");
        System.out.println(selectedMeal.getReservedMeal().size());
        try {
            System.out.println("2");
            mealSessionBean.deleteMeal(selectedMeal);
            setStatusMessage("Meal deleted Successfully");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Delete Meal Result: " + getStatusMessage() + " (Meal deleted is " + selectedMeal.getName() + ")", ""));
        } catch (DeleteProductException del) {
            System.out.println("3");
            setStatusMessage("Meal Exception: ");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delete Meal Result: " + getStatusMessage() + del.getMessage(), ""));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        selectedMeal = new MealEntity();
    }

    public void deleteSetMeal(ActionEvent event) {
        try {
            System.out.println("1");
            mealSessionBean.deleteSetMeal(selectedSetMeal);
            System.out.println("2");
            setStatusMessage("Set Meal deleted Successfully");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Delete Set Meal Result: " + getStatusMessage() + " (Set Meal deleted is " + selectedSetMeal.getName() + ")", ""));
        } catch (DeleteProductException del) {
            setStatusMessage("Set Meal Exception: ");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delete Set Meal Result: " + getStatusMessage() + del.getMessage(), ""));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        selectedSetMeal = new SetMealEntity();
    }
    //getter and setter

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MealSessionBean getMealSessionBean() {
        return mealSessionBean;
    }

    public void setMealSessionBean(MealSessionBean mealSessionBean) {
        this.mealSessionBean = mealSessionBean;
    }

    public void setMealList(List<MealEntity> mealList) {
        this.mealList = mealList;
    }

    public MealEntity getSelectedMeal() {
        return selectedMeal;
    }

    public void setSelectedMeal(MealEntity selectedMeal) {
        this.selectedMeal = selectedMeal;
    }

    public MealEntity[] getSelectedMeals() {
        return selectedMeals;
    }

    public void setSelectedMeals(MealEntity[] selectedMeals) {
        this.selectedMeals = selectedMeals;
    }

    public SetMealEntity getSelectedSetMeal() {
        return selectedSetMeal;
    }

    public void setSelectedSetMeal(SetMealEntity selectedSetMeal) {
        this.selectedSetMeal = selectedSetMeal;
    }

    public List<SetMealEntity> getSetMealList() {
        return setMealList;
    }

    public void setSetMealList(List<SetMealEntity> setMealList) {
        this.setMealList = setMealList;
    }

    public List<FoodTypeEntity> getFoodTypes() {
        return foodTypes;
    }

    public void setFoodTypes(List<FoodTypeEntity> foodTypes) {
        this.setFoodTypes(foodTypes);
    }

    public Long getOption() {
        return option;
    }

    public void setOption(Long option) {
        this.option = option;
    }

    public List getOptions() {
        return options;
    }

    public void setOptions(List options) {
        this.options = options;
    }

    public MealEntity[] getSelectedMeals_update() {
        return selectedMeals_update;
    }

    public void setSelectedMeals_update(MealEntity[] selectedMeals_update) {
        this.selectedMeals_update = selectedMeals_update;
    }

    public boolean isReload() {
        return reload;
    }

    public void setReload(boolean reload) {
        this.reload = reload;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }

    public List<MealEntity> getMealOfBranch() {
        return mealOfBranch;
    }

    public void setMealOfBranch(List<MealEntity> mealOfBranch) {
        this.mealOfBranch = mealOfBranch;
    }

    public boolean checkStakeholder() throws IOException {
        StakeholderEntity stakeholder = (StakeholderEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholder");
        if (stakeholder == null || stakeholder.getId() == null) {
            FacesContext.getCurrentInstance().getExternalContext().redirect("StakeholderLogin.xhtml");
            return false;
        }
        return true;
    }

    public boolean checkBranch() throws IOException {
        if (!checkStakeholder()) {
            return false;
        }
        selectedBranch = (FnBBranchEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedBranch");
        if (selectedBranch == null || selectedBranch.getId() == null) {
            FacesContext.getCurrentInstance().getExternalContext().redirect("StakeholderViewAllBranch.xhtml");
            return false;
        }
        return true;
    }

    public boolean checkMeal() throws IOException {
        if (!checkBranch()) {
            return false;
        }
        selectedMeal = (MealEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedMeal");
        if (selectedMeal == null || selectedMeal.getId() == null) {
            FacesContext.getCurrentInstance().getExternalContext().redirect("StakeholderViewMeals.xhtml");
            return false;
        }
        return true;
    }
    
        public boolean checkSetMeal() throws IOException {
        if (!checkBranch()) {
            return false;
        }
        selectedSetMeal = (SetMealEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedSetMeal");
        if (selectedSetMeal == null || selectedSetMeal.getId() == null) {
            FacesContext.getCurrentInstance().getExternalContext().redirect("StakeholderViewSetMeals.xhtml");
            return false;
        }
        return true;
    }
}
